﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;

namespace FtpCrawler
{
    /// <summary>
    /// 将文件信息存放至数据库中
    /// </summary>
    public class DbStoreProcessor : IFileProcessor
    {
        private string _connString = null;
        private SqlConnection _connection = null;
        private SqlCommand _cmd = null;
        private DateTime _startTime;
        private DateTime _endTime;

        private int _fileCount = 0;
        private int _errorCount = 0;

        public DbStoreProcessor(string connString)
        {
            this.ConnString = connString;
        }

        public string ConnString
        {
            get { return _connString; }
            set { _connString = value; }
        }

        public int FileCount
        {
            get { return _fileCount; }
            set { _fileCount = value; }
        }

        public int ErrorCount
        {
            get { return _errorCount; }
            set { _errorCount = value; }
        }

        /// <summary>
        /// 初始化数据库连接
        /// </summary>
        private void InitConnection()
        {
            if (this._connection == null)
            {
                try
                {
                    this._connection = new SqlConnection(this.ConnString);
                }
                catch (SqlException sqlEx)
                {
                    // 数据库连接错误
                    // throw sqlEx;
                    return;
                }
            }
        }

        public int GetFilesCount()
        {
            return this._fileCount;
        }

        /// <summary>
        /// 处理文件信息，使用数据库事务批量提交
        /// </summary>
        /// <param name="fileInfo"></param>
        public void ProcessFile(FtpFileInfo fileInfo)
        {
            // 拼装插入语句
            string strInsert = "INSERT INTO [FtpSearchEngine].[dbo].[t_fileinfo] " +
                "([is_file],[filename],[access_mode],[num_links]," +
                "[owner],[group],[size],[path],[modified_time]) " +
                "VALUES(@IsFile,@Filename,@AccessMode,@NumLinks,@Ower,@Group,@Size,@Path,@ModifiedTime)";
            SqlParameter[] sqlParams = {
                                            new SqlParameter("@IsFile", SqlDbType.SmallInt),
                                            new SqlParameter("@Filename", SqlDbType.VarChar, 200), 
                                            new SqlParameter("@AccessMode", SqlDbType.Char, 10), 
                                            new SqlParameter("@NumLinks", SqlDbType.Int), 
                                            new SqlParameter("@Ower", SqlDbType.Char, 20), 
                                            new SqlParameter("@Group", SqlDbType.Char, 20), 
                                            new SqlParameter("@Size", SqlDbType.BigInt), 
                                            new SqlParameter("@Path", SqlDbType.VarChar), 
                                            new SqlParameter("@ModifiedTime", SqlDbType.DateTime)

            };
            sqlParams[0].Value = fileInfo.IsFile ? 1 : 0;   // 是否为文件
            sqlParams[1].Value = fileInfo.Filename;
            sqlParams[2].Value = fileInfo.AccessMode;
            sqlParams[3].Value = fileInfo.NumLinks;
            sqlParams[4].Value = fileInfo.Owner;
            sqlParams[5].Value = fileInfo.Group;
            sqlParams[6].Value = fileInfo.Size;
            sqlParams[7].Value = fileInfo.Path;
            sqlParams[8].Value = fileInfo.ModifiedTime;

            try
            {
                SqlCommand cmd = new SqlCommand(strInsert, this._connection);
                cmd.Parameters.AddRange(sqlParams);
                this._connection.Open();
                cmd.ExecuteNonQuery();
            }
            catch (SqlException sqlEx)
            {
                // 数据库连接错误
                // throw sqlEx;
                return;
            }
            finally
            {
                if (this._connection != null)
                {
                    this._connection.Close();
                }
            }

            this.FileCount++;
            //Console.WriteLine("[Success]: " + fileInfo.Path + fileInfo.Filename);
        }

        /// <summary>
        /// 处理错误信息
        /// </summary>
        /// <param name="msg"></param>
        public void ProcessError(string msg)
        {
            this.ErrorCount++;

            //Console.WriteLine("[Error]: " + msg);

            // 拼装插入语句
            string strInsert = "INSERT INTO [FtpSearchEngine].[dbo].[t_operlog] " +
                "([src],[location],[message],[time],[memo]) " +
                "VALUES(@Src,@Location,@Message,@Time,@Memo) ";

            SqlParameter[] sqlParams = {
                                            new SqlParameter("@Src", SqlDbType.Char, 10),
                                            new SqlParameter("@Location", SqlDbType.VarChar, 50), 
                                            new SqlParameter("@Message", SqlDbType.VarChar), 
                                            new SqlParameter("@Time", SqlDbType.DateTime), 
                                            new SqlParameter("@Memo", SqlDbType.VarChar, 50)

            };
            sqlParams[0].Value = "CrawlError";
            sqlParams[1].Value = "";
            sqlParams[2].Value = msg;
            sqlParams[3].Value = DateTime.Now;
            sqlParams[4].Value = "检索记录错误";

            try
            {
                SqlCommand cmd = new SqlCommand(strInsert, this._connection);
                cmd.Parameters.AddRange(sqlParams);
                this._connection.Open();
                cmd.ExecuteNonQuery();
            }
            catch (SqlException sqlEx)
            {
                // 数据库连接错误
                // throw sqlEx;
                return;
            }
            finally
            {
                if (this._connection != null)
                {
                    this._connection.Close();
                }
            }

        }

        /// <summary>
        /// 文件列表开始处理
        /// </summary>
        public void StartProcess()
        {
            this.InitConnection();
            this._startTime = DateTime.Now;

            // 拼装插入语句
            string strInsert = "INSERT INTO [FtpSearchEngine].[dbo].[t_operlog] " +
                "([src],[location],[message],[time],[memo]) " +
                "VALUES(@Src,@Location,@Message,@Time,@Memo) ";

            SqlParameter[] sqlParams = {
                                            new SqlParameter("@Src", SqlDbType.Char, 10),
                                            new SqlParameter("@Location", SqlDbType.VarChar, 50), 
                                            new SqlParameter("@Message", SqlDbType.VarChar), 
                                            new SqlParameter("@Time", SqlDbType.DateTime), 
                                            new SqlParameter("@Memo", SqlDbType.VarChar, 50)

            };
            sqlParams[0].Value = "StartCrawl";
            sqlParams[1].Value = "";
            sqlParams[2].Value = "开始抓取记录";
            sqlParams[3].Value = DateTime.Now;
            sqlParams[4].Value = "";

            try
            {
                SqlCommand cmd = new SqlCommand(strInsert, this._connection);
                cmd.Parameters.AddRange(sqlParams);
                this._connection.Open();
                cmd.ExecuteNonQuery();
            }
            catch (SqlException sqlEx)
            {
                // 数据库连接错误
                // throw sqlEx;
                return;
            }
            finally
            {
                if (this._connection != null)
                {
                    this._connection.Close();
                }
            }
        }

        /// <summary>
        /// 文件列表处理完成
        /// </summary>
        public void ProcessCompleted()
        {
            this._endTime = DateTime.Now;

            // 拼装插入语句
            string strInsert = "INSERT INTO [FtpSearchEngine].[dbo].[t_operlog] " +
                "([src],[location],[message],[time],[memo]) " +
                "VALUES(@Src,@Location,@Message,@Time,@Memo) ";

            SqlParameter[] sqlParams = {
                                            new SqlParameter("@Src", SqlDbType.Char, 10),
                                            new SqlParameter("@Location", SqlDbType.VarChar, 50), 
                                            new SqlParameter("@Message", SqlDbType.VarChar), 
                                            new SqlParameter("@Time", SqlDbType.DateTime), 
                                            new SqlParameter("@Memo", SqlDbType.VarChar, 50)

            };
            sqlParams[0].Value = "EndCrawl";
            sqlParams[1].Value = "";
            sqlParams[2].Value = string.Format("处理文件+目录数：{0}个，错误数：{1}个。总共耗时{2}",
                this._fileCount, this._errorCount, (this._endTime - this._startTime));
            sqlParams[3].Value = DateTime.Now;
            sqlParams[4].Value = "检索记录完成";

            try
            {
                SqlCommand cmd = new SqlCommand(strInsert, this._connection);
                cmd.Parameters.AddRange(sqlParams);
                this._connection.Open();
                cmd.ExecuteNonQuery();
            }
            catch (SqlException sqlEx)
            {
                // 数据库连接错误
                // throw sqlEx;
                return;
            }
            finally
            {
                if (this._connection != null)
                {
                    this._connection.Close();
                }
            }
        }
    }
}
